﻿using CubeCube.Tile;
using System;

namespace CubeCube.Utils
{
    public class Graphics
    {
        public const float TILE_SIZE = 1.0f;
        public const float HALF_TILE_SIZE = TILE_SIZE / 2.0f;
        public const float QUART_TILE_SIZE = TILE_SIZE / 4.0f;

        public const float ITEM_TILE_SIZE = TILE_SIZE * 0.25f;

        public const int SECTOR_SIZE_BITS = 4;
        public const int SECTOR_SIZE = 1 << SECTOR_SIZE_BITS;

        public const int CHUNK_SIZE_BITS = 8;     //chunck的大小,一个块容纳的sector的个数不能超过1024
        public const int CHUNK_SIZE = 1 << CHUNK_SIZE_BITS;

        public const int MAX_MAP_Y_SIZE_BITS = CHUNK_SIZE_BITS;         //根据设计需要，世界Y轴方向只能有一个chunk
        public const int MAX_MAP_Y_SIZE = 1 << MAX_MAP_Y_SIZE_BITS;
        public const int MAX_MAP_XZ_SIZE_BIT = 12;
        public const int MAX_MAP_XZ_SIZE = 1 << MAX_MAP_XZ_SIZE_BIT;

        private const int MAP_HALF_XZ_SIZE = MAX_MAP_XZ_SIZE >> 1;
        public const int MAP_RIGHT_BORDER = MAP_HALF_XZ_SIZE - 1;
        public const int MAP_LEFT_BORDER = -MAP_HALF_XZ_SIZE;
        public const int MAP_FRONT_BORDER = MAP_HALF_XZ_SIZE - 1;
        public const int MAP_BACK_BORDER = -MAP_HALF_XZ_SIZE;
        public const int MAP_TOP_BORDER = MAX_MAP_Y_SIZE - 1;
        public const int MAP_BOTTOM_BORDER = 0;

        public enum Faces
        {
            Back = 0,
            Front,
            Down,
            Up,
            Right,
            Left,
            Count
        }

        public static readonly IndexPosition[] FACE_DIR_VECTOR = new IndexPosition[(int)Faces.Count]
        {
            new IndexPosition(0, 0, -1),
            new IndexPosition(0, 0, 1),
            new IndexPosition(0, -1, 0),
            new IndexPosition(0, 1, 0),
            new IndexPosition(-1, 0, 0),
            new IndexPosition(1, 0 , 0)
        };


        static public IndexPosition TilePositionToChunkPosition(IndexPosition pos)
        {
            return new IndexPosition(
                (int)Math.Floor((float)pos.x / CHUNK_SIZE) * CHUNK_SIZE,
                (int)Math.Floor((float)pos.y / CHUNK_SIZE) * CHUNK_SIZE,
                (int)Math.Floor((float)pos.x / CHUNK_SIZE) * CHUNK_SIZE);
        }

        static public Vector TilePositionToVector3(IndexPosition pos)
        {
            return new Vector(pos.x * TILE_SIZE, pos.y * TILE_SIZE, pos.z * TILE_SIZE);
        }

        static public IndexPosition Vector3ToTileIndexPosition(Vector vec)
        {
            return new IndexPosition(
                (int)Math.Round(vec.x / TILE_SIZE),
                (int)Math.Round(vec.y / TILE_SIZE),
                (int)Math.Round(vec.z / TILE_SIZE));
        }

    }
}
